using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;

namespace Waaahsabi.Controls.TheGame
{
	public class ChatControl: Control
	{
#pragma warning disable 67
		public event EventHandler<ChatControlMessageEventArgs> SendMessage;
		public event EventHandler SpamDetected;
#pragma warning restore 67
		#region ChatMessages DependencyProperty
		public static readonly DependencyProperty ChatMessagesProperty =
		DependencyProperty.Register
			(
			"ChatMessages",
			typeof(ObservableCollection<ChatMessageItem>),
			typeof(ChatControl),
			new PropertyMetadata(null)
			);

		public ObservableCollection<ChatMessageItem> ChatMessages
		{
			get { return (ObservableCollection<ChatMessageItem>)GetValue(ChatMessagesProperty); }
			set { SetValue(ChatMessagesProperty, value); }
		}
		#endregion

		#region InputVisibility DependencyProperty
		public static readonly DependencyProperty InputVisibilityProperty =
		DependencyProperty.Register
			(
			"InputVisibility",
			typeof(Visibility),
			typeof(ChatControl),
			new PropertyMetadata(Visibility.Visible)
			);

		public Visibility InputVisibility
		{
			get { return (Visibility)GetValue(InputVisibilityProperty); }
			set { SetValue(InputVisibilityProperty, value); }
		}
		#endregion

		private TextBox _txtMessage;
		private ScrollViewer _scrollViewer;
		private ToggleButton _btnPin;
		private bool _isPinned;
		private ItemsControl _itmMessages;
		private readonly Stopwatch _stopWatch;
		public ChatControl()
		{
			DefaultStyleKey = typeof (ChatControl);
			ChatMessages = new ObservableCollection<ChatMessageItem>();
			_stopWatch = new Stopwatch();
		}

		void ChatMessagesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
		{
			UpdateLayout();
			if (_scrollViewer != null)
			{
				_scrollViewer.ScrollToVerticalOffset(double.MaxValue);
				//new Thread(new ThreadStart(delegate
				//{
				//    Thread.Sleep(100);
				//    Dispatcher.BeginInvoke(delegate
				//    {
				//    });
				//})).Start();
			}
		}

		public override void OnApplyTemplate()
		{
			base.OnApplyTemplate();
			ChatMessages.CollectionChanged += ChatMessagesCollectionChanged;
			
			MouseEnter += TxtMessageGotFocus;
			MouseLeave += TxtMessageLostFocus;

			_txtMessage = GetTemplateChild("txtMessage") as TextBox;
			if(_txtMessage != null)
			{
				_txtMessage.KeyDown += TxtMessageKeyDown;
			}

			_scrollViewer = GetTemplateChild("scrollViewer") as ScrollViewer;
			if(_scrollViewer != null)
			{
			}

			_itmMessages = GetTemplateChild("itmMessages") as ItemsControl;
			if (_itmMessages != null)
			{
				_itmMessages.MouseWheel += (s, e) =>
				{
					e.Handled = false;
				};
			}
			_btnPin = GetTemplateChild("btnPin") as ToggleButton;
			if(_btnPin != null)
			{
				_btnPin.Click += BtnPinClick;
			}
		}

		void BtnPinClick(object sender, RoutedEventArgs e)
		{
			_isPinned = _btnPin.IsChecked != null ? _btnPin.IsChecked.Value : false;
		}

		void TxtMessageLostFocus(object sender, RoutedEventArgs e)
		{
			if (!_isPinned)
				VisualStateManager.GoToState(this, "Collapsed", true);
		}

		void TxtMessageGotFocus(object sender, RoutedEventArgs e)
		{
			VisualStateManager.GoToState(this, "Extended", true);
		}

		void TxtMessageKeyDown(object sender, KeyEventArgs e)
		{
			if(e.Key == Key.Enter)
			{
				if (string.IsNullOrEmpty(_txtMessage.Text))
					return;

				if (_stopWatch.IsRunning)
				{
					_stopWatch.Stop();
					if (_stopWatch.ElapsedMilliseconds < 4000)
						return;
				}

				if (SendMessage != null)
					SendMessage(this, new ChatControlMessageEventArgs {Message = _txtMessage.Text});
				_txtMessage.Text = "";
				_stopWatch.Reset();
				_stopWatch.Start();
			}
		}

		public void ToggleInput(bool visible)
		{
			if(_txtMessage != null)
			{
				_txtMessage.Visibility = visible ? Visibility.Visible : Visibility.Collapsed;
			}
		}
	}
}